package br.uff.probabilidade.modelo.tabuleiro;

import java.awt.Point;
import java.util.Random;
import java.util.Vector;

import sun.java2d.SunGraphicsEnvironment.TTFilter;

import br.uff.probabilidade.applet.Atividade;
import br.uff.probabilidade.applet.Tabuleiro;
import br.uff.probabilidade.modelo.Evento;
import br.uff.probabilidade.modelo.Imagem;
import br.uff.probabilidade.modelo.Operacao;
import br.uff.probabilidade.modelo.Quadrado;

public class Desafio {
	private Vector niveis  = new Vector();
	private Vector grupamentos  = new Vector();
	private Nivel nivelAtual;		
	private boolean ativo = false;
	private boolean novo = true;
	
	private String mensagemInicial=" ";
	
	private int[] sorteio = null;
	
	private Vector eventos = new Vector();
	
	public void addEvento(Evento evento){		
		this.eventos.add(evento);
	}
	
	public Grupamento addEventoToNivel(Evento evento,Nivel nivel){	
		boolean temGrupo = false;
				
		Vector gruposIndice = new Vector();
		for(int i=0;i<grupamentos.size();i++)
			if(this.getGrupamentoAt(i).pertence(evento)){
				gruposIndice.add(i);
				temGrupo = true;
			}
		
		if(temGrupo){
			int sorteiaGrupo = new Random().nextInt(gruposIndice.size());
			Grupamento grupamento = this.getGrupamentoAt((Integer)gruposIndice.get(sorteiaGrupo));
			for(int j=0;j<grupamento.qntEventos();j++){
				nivel.addEventoAgrupado(grupamento.getEventoAt(j));				
			}
			return grupamento;
		}
		
		nivel.addEvento(evento);
		return null;
	}
	
	public Operacao addEventoToNivel(Evento evento,boolean comOperacoes,int nivelIndice){
		Grupamento grupamento = this.addEventoToNivel(evento, this.getNivel(nivelIndice)); 
		if(grupamento!=null){			
			Operacao sorteada = grupamento.sorteiaOperacao();
			//if(nivelIndice+1<this.niveis.size()){
			//	this.getNivel(nivelIndice+1).addOperacao(sorteada);
			//	this.getNivel(nivelIndice+1).addHeranca(this.getNivel(nivelIndice));
			//}
			if(comOperacoes)
				this.getNivel(nivelIndice).addOperacao(sorteada);
			
			return sorteada;
		}
		return null;
	}
	
	public void addGrupamento(Grupamento grupamento){
		this.grupamentos.add(grupamento);
	}
	
	public Grupamento getGrupamentoAt(int i){
		return (Grupamento)this.grupamentos.get(i);
	}
	
	public boolean isNew(){
		return this.novo;
	}
	
	public Evento getEventoAt(int i){
		return (Evento)this.eventos.get(i);
	}
	
	public Evento getEventoSorteioAt(int i){
		return this.getEventoAt(this.sorteio[i]);
	}
	
	public void sorteia(){
		System.out.println("Soooorteando ...");
		int total = this.eventos.size();
		int[] posicoes = new int[total];
		for(int i=0;i<total;i++){
			posicoes[i]=i;
		}
		
		int i=0,qnt=0,tmp;
		while(qnt<total){
			i = new Random().nextInt(total-qnt);		
			tmp = posicoes[total-1];
			posicoes[total-1] = posicoes[i];
			posicoes[i] = tmp;
			qnt++;
		}
		
		this.sorteio = posicoes;
	}
	
	
	public Desafio(int numNiveis,Atividade atividade){		
		for(int i=0;i<numNiveis;i++)
			this.niveis.add(new Nivel(atividade));					
	}	
		
	
	public void inicia(Imagem check){		
		if(this.qntNiveis()>0){
			this.nivelAtual =this.getNivel(0); 
			this.nivelAtual.monta(check);
		}			
	}
	
	public boolean isCompleto(){
		for(int i=0;i<this.niveis.size();i++){    					
			if(!this.getNivel(i).isCompleto()){
				return false;     				    			
			}    			    		
    	}
		return true;
	}
	
	public boolean hasProximoNivel(){		
		return !(this.getNivel(this.qntNiveis()-1).isAtivo());
	}
	
	public Nivel proximoNivel(Imagem check) throws Exception{
		if(this.getNivelAtual()!=null){
			if(this.getNivelAtual().isCompleto()){
				for(int i=0;i<this.niveis.size();i++){
		    		if(this.getNivel(i).isAtivo()){
		    			this.getNivel(i).setAtivo(false);
		    			if(i+1<this.niveis.size()){
		    				this.getNivel(i+1).setAtivo(true);
		    				this.nivelAtual = this.getNivel(i+1); 
		    				this.getNivel(i+1).monta(check);
		    				
		    				return this.nivelAtual;
		    			}		    					    		
		    		}
		    	}
			}else
				throw new Exception("Nivel Incompleto");
		}else if(this.niveis.size()>0){
    		this.getNivel(0).setAtivo(true);
    		this.nivelAtual = this.getNivel(0);
    		this.getNivel(0).monta(check);    		
    	}		
		return null;
	}
	
	public Nivel getNivelAtual(){
		return nivelAtual;
	}
	
	public Nivel getNivel(int i){
		return (Nivel)this.niveis.get(i);
	}
	
	public int qntNiveis(){
		return this.niveis.size();
	}

	public boolean isAtivo() {
		return ativo;
	}

	public void setAtivo(boolean ativo) {
		this.ativo = ativo;
		if(this.isAtivo())
			this.novo = false;
	}

	public String getMensagemInicial() {
		return mensagemInicial;
	}

	public void setMensagemInicial(String mensagemInicial) {
		this.mensagemInicial = mensagemInicial;
	}
	
	
	
}
